package com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.partIn.taskPostHandler;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.cmdb.CMDBPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.PartInTaskFormDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.domainDto.FlowFormPartInDto;
import com.glsc.ngateway.common.api.oaflow.feign.IFeignOaFlowService;
import com.glsc.ngateway.common.api.oaflow.resp.InterfaceResponse;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbCpuDetail;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbDiskDetail;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbMemoryDetail;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbPartDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowPushOaLog;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormCPUInDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormDiskInDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormMemoryInDetail;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormPartInDetail;
import com.glsc.ngateway.common.base.domain.oracle.ecology.UfZcinfo;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowTaskEnum;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbCpuDetailRepository;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbDiskDetailRepository;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbMemoryDetailRepository;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbPartDetailRepository;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.FlowFormCPUInDetailRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.FlowFormDiskInDetailRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.FlowFormMemoryInDetailRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.FlowFormPartInDetailRepo;
import com.glsc.ngateway.common.base.repo.oracle.ecology.UfZcinfoRepository;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.IItFlowMQHandler;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.partIn.PartInFlowStrategy;
import lombok.SneakyThrows;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class PIStep4SyncOaTaskPostHandlerAudit implements IPartInTaskPostHandlerAudit, IItFlowMQHandler {

    @Resource
    PartInFlowStrategy partInFlowStrategy;
    @Resource
    PIStepHandlerHelper handlerHelper;
    @Resource
    private FlowFormCPUInDetailRepo cpuInDetailRepo;
    @Resource
    private FlowFormMemoryInDetailRepo memoryInDetailRepo;
    @Resource
    private FlowFormDiskInDetailRepo diskInDetailRepo;
    @Resource
    private FlowFormPartInDetailRepo partInDetailRepo;
    @Resource
    private IFeignOaFlowService feignOaFlowService;
    @Resource
    private CmdbCpuDetailRepository cpuDetailRepository;
    @Resource
    private CmdbMemoryDetailRepository memoryDetailRepository;
    @Resource
    private CmdbDiskDetailRepository diskDetailRepository;
    @Resource
    private CmdbPartDetailRepository partDetailRepository;
    @Resource
    private UfZcinfoRepository zcinfoRepository;

    @Override
    public void doHandle(String msg) throws UnsupportedEncodingException {

    }

    @Override
    public String getTaskDefinitionKey() {
        return ITFlowTaskEnum.CMDB_PART_IN_FLOW_SYNC_OA_TASK.getTaskKey();
    }

    @SneakyThrows
    @Override
    public void endFromOaFlow(FlowPushOaLog log, String description) {
        //修改服务器编号
        InterfaceResponse requestData = JSON.parseObject(feignOaFlowService.getRequestData(log.getRequestId()), InterfaceResponse.class);
        List<Map<String, JSONObject>> data = (List<Map<String, JSONObject>>) requestData.getData();
        JSONObject flowInfos = data.get(0).get("flowInfos");
        List<JSONObject> detailList = (List<JSONObject>) flowInfos.get("detailMap");
        Map<String, String> sn2Zcbhmap = detailList.stream().collect(Collectors.toMap(f -> f.get("sn").toString(), f -> f.get("zcbh").toString(), (o1, o2) -> o1));
        Map<String, UfZcinfo> zcbmMap = zcinfoRepository.findAllById(sn2Zcbhmap.values()).stream().collect(Collectors.toMap(UfZcinfo::getId, o -> o));
        List<FlowFormCPUInDetail> cpuForm = cpuInDetailRepo.findAllByprocessId(log.getProcessId());
        if (CollectionUtil.isNotEmpty(cpuForm)) {
            List<String> cpuDetailCodes = cpuForm.stream().map(FlowFormCPUInDetail::getCpuDetailCode).filter(Strings::isNotBlank).collect(Collectors.toList());
            List<CmdbCpuDetail> cpuDetails = cpuDetailRepository.findAllByCpuDetailCodeIn(cpuDetailCodes);
            cpuDetails = cpuDetails.stream()
                    .peek(d ->
                            Optional.ofNullable(zcbmMap.get(sn2Zcbhmap.get(d.getSn()))).ifPresent(ufzc -> {
                                d.setAssertNum(ufzc.getZcbm());
                                d.setAssertId(ufzc.getId());
                            })
                    )
                    .collect(Collectors.toList());
            cpuDetailRepository.saveAll(cpuDetails);
        }
        List<FlowFormMemoryInDetail> memoryForm = memoryInDetailRepo.findAllByprocessId(log.getProcessId());
        if (CollectionUtil.isNotEmpty(memoryForm)) {
            List<String> memoryDetailCodes = memoryForm.stream().map(FlowFormMemoryInDetail::getMemoryDetailCode).filter(Strings::isNotBlank).collect(Collectors.toList());
            List<CmdbMemoryDetail> memoryDetails = memoryDetailRepository.findAllByMemoryDetailCodeIn(memoryDetailCodes);
            memoryDetails = memoryDetails.stream()
                    .peek(d ->
                            Optional.ofNullable(zcbmMap.get(sn2Zcbhmap.get(d.getSn()))).ifPresent(ufzc -> {
                                d.setAssertNum(ufzc.getZcbm());
                                d.setAssertId(ufzc.getId());
                            })
                    )
                    .collect(Collectors.toList());
            memoryDetailRepository.saveAll(memoryDetails);
        }
        List<FlowFormDiskInDetail> diskForm = diskInDetailRepo.findAllByprocessId(log.getProcessId());
        if (CollectionUtil.isNotEmpty(diskForm)) {
            List<String> diskDetailCodes = diskForm.stream().map(FlowFormDiskInDetail::getDiskDetailCode).filter(Strings::isNotBlank).collect(Collectors.toList());
            List<CmdbDiskDetail> cpuDetails = diskDetailRepository.findAllByDiskDetailCodeIn(diskDetailCodes);
            cpuDetails = cpuDetails.stream()
                    .peek(d ->
                            Optional.ofNullable(zcbmMap.get(sn2Zcbhmap.get(d.getSn()))).ifPresent(ufzc -> {
                                d.setAssertNum(ufzc.getZcbm());
                                d.setAssertId(ufzc.getId());
                            })
                    )
                    .collect(Collectors.toList());
            diskDetailRepository.saveAll(cpuDetails);
        }
        List<FlowFormPartInDetail> partForm = partInDetailRepo.findAllByprocessId(log.getProcessId());
        if (CollectionUtil.isNotEmpty(partForm)) {
            List<String> partDetailCodes = partForm.stream().map(FlowFormPartInDetail::getPartDetailCode).filter(Strings::isNotBlank).collect(Collectors.toList());
            List<CmdbPartDetail> partDetails = partDetailRepository.findAllByPartDetailCodeIn(partDetailCodes);
            partDetails = partDetails.stream()
                    .peek(d ->
                            Optional.ofNullable(zcbmMap.get(sn2Zcbhmap.get(d.getSn()))).ifPresent(ufzc -> {
                                d.setAssertNum(ufzc.getZcbm());
                                d.setAssertId(ufzc.getId());
                            })
                    )
                    .collect(Collectors.toList());
            partDetailRepository.saveAll(partDetails);
        }
        //结束流程
        CMDBPassParamDto<FlowFormPartInDto, PartInTaskFormDto> param = new CMDBPassParamDto<>();
        param.setProcessId(log.getProcessId());
        param.setTaskId(log.getTaskId());
        param.setTaskDefinitionKey(log.getTaskKey());
//        param.setFlowableFormData();
        partInFlowStrategy.taskAuditPass(param, log.getCreator());
    }

    @Override
    public String getMqCodeKey() {
        return ITFlowTaskEnum.CMDB_PART_IN_FLOW_SYNC_OA_TASK.getMqCodeKey();
    }

}
